home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_11 / plauger / complex.cpp < prev   
Encoding:
C/C++ Source or Header  |  1995-09-11  |  18.1 KB  |  610 lines

  1. // complex standard header
  2. #ifndef _COMPLEX_
  3. #define _COMPLEX_
  4. #include <cmath>
  5. #include <istream>
  6. _STD_BEGIN
  7. #define __STD_COMPLEX
  8.         // TEMPLATE CLASS _Ctr
  9. template<class _T> class _Ctr {
  10. public:
  11.     static _T _Cosh(_T _X, _T _Y)
  12.         {return (::_Cosh((double)_X, (double)_Y)); }
  13.     static short _Exp(_T *_P, _T _Y, short _E)
  14.         {double _W = (double)*_P;
  15.         short _Ans = ::_Exp(&_W, (double)_Y, _E);
  16.         *_P = (_T)_W;
  17.         return (_Ans); }
  18.     static _T _Infv(_T)
  19.         {return (_Inf._D); }
  20.     static bool _Isinf(_T _X)
  21.         {double _W = (double)_X;
  22.         return (_Dtest(&_W) == _INF); }
  23.     static bool _Isnan(_T _X)
  24.         {double _W = (double)_X;
  25.         return (_Dtest(&_W) == _NAN); }
  26.     static _T _Nanv(_T)
  27.         {return (_Nan._D); }
  28.     static _T _Sinh(_T _X, _T _Y)
  29.         {return (::_Sinh((double)_X, (double)_Y)); }
  30.     static _T atan2(_T _Y, _T _X)
  31.         {return (::atan2((double)_Y, (double)_X)); }
  32.     static _T cos(_T _X)
  33.         {return (::cos((double)_X)); }
  34.     static _T exp(_T _X)
  35.         {return (::exp((double)_X)); }
  36.     static _T ldexp(_T _R, int _E)
  37.         {return (::ldexp((double)_R, _E)); }
  38.     static _T log(_T _X)
  39.         {return (::log((double)_X)); }
  40.     static _T pow(_T _X, _T _Y)
  41.         {return (::pow((double)_X, (double)_Y)); }
  42.     static _T sin(_T _X)
  43.         {return (::sin((double)_X)); }
  44.     static _T sqrt(_T _X)
  45.         {return (::sqrt((double)_X)); }
  46.     };
  47.         // CLASS _Ctr<float>
  48. class _Ctr<float> {
  49. public:
  50.     typedef float _T;
  51.     static _T _Cosh(_T _X, _T _Y)
  52.         {return (_FCosh(_X, _Y)); }
  53.     static short _Exp(_T *_P, _T _Y, short _E)
  54.         {return (_FExp(_P, _Y, _E)); }
  55.     static _T _Infv(_T)
  56.         {return (_FInf._F); }
  57.     static bool _Isinf(_T _X)
  58.         {return (_FDtest(&_X) == _INF); }
  59.     static bool _Isnan(_T _X)
  60.         {return (_FDtest(&_X) == _NAN); }
  61.     static _T _Nanv(_T)
  62.         {return (_FNan._F); }
  63.     static _T _Sinh(_T _X, _T _Y)
  64.         {return (_FSinh(_X, _Y)); }
  65.     static _T atan2(_T _Y, _T _X)
  66.         {return (atan2f(_Y, _X)); }
  67.     static _T cos(_T _X)
  68.         {return (cosf(_X)); }
  69.     static _T exp(_T _X)
  70.         {return (expf(_X)); }
  71.     static _T ldexp(_T _R, int _E)
  72.         {return (ldexpf(_R, _E)); }
  73.     static _T log(_T _X)
  74.         {return (logf(_X)); }
  75.     static _T pow(_T _X, _T _Y)
  76.         {return (powf(_X, _Y)); }
  77.     static _T sin(_T _X)
  78.         {return (sinf(_X)); }
  79.     static _T sqrt(_T _X)
  80.         {return (sqrtf(_X)); }
  81.     };
  82.         // CLASS _Ctr<double>
  83. class _Ctr<double> {
  84. public:
  85.     typedef double _T;
  86.     static _T _Cosh(_T _X, _T _Y)
  87.         {return (::_Cosh(_X, _Y)); }
  88.     static short _Exp(_T *_P, _T _Y, short _E)
  89.         {return (::_Exp(_P, _Y, _E)); }
  90.     static _T _Infv(_T)
  91.         {return (_Inf._D); }
  92.     static bool _Isinf(_T _X)
  93.         {return (_Dtest(&_X) == _INF); }
  94.     static bool _Isnan(_T _X)
  95.         {return (_Dtest(&_X) == _NAN); }
  96.     static _T _Nanv(_T)
  97.         {return (_Nan._D); }
  98.     static _T _Sinh(_T _X, _T _Y)
  99.         {return (::_Sinh(_X, _Y)); }
  100.     static _T atan2(_T _Y, _T _X)
  101.         {return (::atan2(_Y, _X)); }
  102.     static _T cos(_T _X)
  103.         {return (::cos(_X)); }
  104.     static _T exp(_T _X)
  105.         {return (::exp(_X)); }
  106.     static _T ldexp(_T _R, int _E)
  107.         {return (::ldexp(_R, _E)); }
  108.     static _T log(_T _X)
  109.         {return (::log(_X)); }
  110.     static _T pow(_T _X, _T _Y)
  111.         {return (::pow(_X, _Y)); }
  112.     static _T sin(_T _X)
  113.         {return (::sin(_X)); }
  114.     static _T sqrt(_T _X)
  115.         {return (::sqrt(_X)); }
  116.     };
  117.         // CLASS _Ctr<long double>
  118. class _Ctr<long double> {
  119. public:
  120.     typedef long double _T;
  121.     static _T _Cosh(_T _X, _T _Y)
  122.         {return (_LCosh(_X, _Y)); }
  123.     static short _Exp(_T *_P, _T _Y, short _E)
  124.         {return (_LExp(_P, _Y, _E)); }
  125.     static _T _Infv(_T)
  126.         {return (_LInf._L); }
  127.     static bool _Isinf(_T _X)
  128.         {return (_LDtest(&_X) == _INF); }
  129.     static bool _Isnan(_T _X)
  130.         {return (_LDtest(&_X) == _NAN); }
  131.     static _T _Nanv(_T)
  132.         {return (_LNan._L); }
  133.     static _T _Sinh(_T _X, _T _Y)
  134.         {return (_LSinh(_X, _Y)); }
  135.     static _T atan2(_T _Y, _T _X)
  136.         {return (atan2l(_Y, _X)); }
  137.     static _T cos(_T _X)
  138.         {return (cosl(_X)); }
  139.     static _T exp(_T _X)
  140.         {return (expl(_X)); }
  141.     static _T ldexp(_T _R, int _E)
  142.         {return (ldexpl(_R, _E)); }
  143.     static _T log(_T _X)
  144.         {return (logl(_X)); }
  145.     static _T pow(_T _X, _T _Y)
  146.         {return (powl(_X, _Y)); }
  147.     static _T sin(_T _X)
  148.         {return (sinl(_X)); }
  149.     static _T sqrt(_T _X)
  150.         {return (sqrtl(_X)); }
  151.     };
  152.         // TEMPLATE CLASS _Complex_base
  153. template<class _T> class complex;
  154. class complex<float>;
  155. class complex<double>;
  156. class complex<long double>;
  157. template<class _T>
  158.     class _Complex_base {
  159. public:
  160.     typedef _Complex_base<_T> _Myt;
  161.     _Complex_base(const _T& _R, const _T& _I)
  162.         : _Re(_R), _Im(_I) {}
  163. #if _HAS_MEMBER_TEMPLATES
  164.     template class<U>
  165.         _Myt& operator=(const complex<_U>& _X)
  166.         {_Re = (_T)_X.real();
  167.         _Im = (_T)_X.imag();
  168.         return (*this); }
  169.     template<class _U>
  170.         _Myt& operator+=(const complex<_U>& _X)
  171.         {_Re += (_T)_X.real();
  172.         _Im += (_T)_X.imag();
  173.         return (*this); }
  174.     template<class _U>
  175.         _Myt& operator-=(const complex<_U>& _X)
  176.         {_Re -= (_T)_X.real();
  177.         _Im -= (_T)_X.imag();
  178.         return (*this); }
  179.     template<class _U>
  180.         _Myt& operator*=(const complex<_U>& _X)
  181.         {_T _Xre = (_T)_X.real();
  182.         _T _Xim = (_T)_X.imag();
  183.         _T _W = _Re * _Xre - _Im * _Xim;
  184.         _Im = _Re * _Xim + _Im * _Xre;
  185.         _Re = _W;
  186.         return (*this); }
  187.     template class<U>
  188.         _Myt& operator/=(const complex<_U>& _X)
  189.         {_T _Xre = (_T)_X.real();
  190.         _T _Xim = (_T)_X.imag();
  191.         if (_Ctr<_T>::_Isnan(_Xre) || _Ctr<_T>::_Isnan(_Xim))
  192.             _Re = _Ctr<_T>::_Nanv(_Xre), _Im = _Re;
  193.         else if ((_Xim < 0 ? -_Xim : +_Xim)
  194.             < (_Xre < 0 ? -_Xre : +_Xre))
  195.             {_T _Wr = _Xim / _Xre;
  196.             _T _Wd = _Xre + _Wr * _Xim;
  197.             if (_Ctr<_T>::_Isnan(_Wd) || _Wd == 0)
  198.                 _Re = _Ctr<_T>::_Nanv(_Xre), _Im = _Re;
  199.             else
  200.                 {_T _W = (_Re + _Im * _Wr) / _Wd;
  201.                 _Im = (_Im - _Re * _Wr) / _Wd;
  202.                 _Re = _W; }}
  203.         else if (_Xim == 0)
  204.             _Re = _Ctr<_T>::_Nanv(_Xre), _Im = _Re;
  205.         else
  206.             {_T _Wr = _Xre / _Xim;
  207.             _T _Wd = _Xim + _Wr * _Xre;
  208.             if (_Ctr<_T>::_Isnan(_Wd) || _Wd == 0)
  209.                 _Re = _Ctr<_T>::_Nanv(_Xre), _Im = _Re;
  210.             else
  211.                 {_T _W = (_Re * _Wr + _Im) / _Wd;
  212.                 _Im = (_Im * _Wr - _Re) / _Wd;
  213.                 _Re = _W; }}
  214.         return (*this); }
  215. #else
  216.     _T real(_T _X)
  217.         {return (_Re = _X); }
  218.     _T imag(_T _X)
  219.         {return (_Im = _X); }
  220. #endif
  221.     _T real() const
  222.         {return (_Re); }
  223.     _T imag() const
  224.         {return (_Im); }
  225. private:
  226.     _T _Re, _Im;
  227.     };
  228.         // CLASS complex<float>
  229. class complex<float> : public _Complex_base<float> {
  230. public:
  231.     typedef float _T;
  232.     explicit complex(const complex<double>&);
  233.     explicit complex(const complex<long double>&);
  234.     complex(const _T& _R = 0, const _T& _I = 0)
  235.         : _Complex_base<_T>(_R, _I) {}
  236.     };
  237.         // CLASS complex<double>
  238. class complex<double> : public _Complex_base<double> {
  239. public:
  240.     typedef double _T;
  241.     complex(const complex<float>&);
  242.     explicit complex(const complex<long double>&);
  243.     complex(const _T& _R = 0, const _T& _I = 0)
  244.         : _Complex_base<_T>(_R, _I) {}
  245.     };
  246.         // CLASS complex<long double>
  247. class complex<long double> : public _Complex_base<long double> {
  248. public:
  249.     typedef long double _T;
  250.     complex(const complex<float>&);
  251.     complex(const complex<double>&);
  252.     complex(const _T& _R = 0, const _T& _I = 0)
  253.         : _Complex_base<_T>(_R, _I) {}
  254.     };
  255.         // CONSTRUCTORS FOR complex SPECIALIZATIONS
  256. complex<float>::complex(const complex<double>& _X)
  257.     : _Complex_base<float>((_T)_X.real(), (_T)_X.imag()) {}
  258. complex<float>::complex(const complex<long double>& _X)
  259.     : _Complex_base<float>((_T)_X.real(), (_T)_X.imag()) {}
  260. complex<double>::complex(const complex<float>& _X)
  261.     : _Complex_base<double>((_T)_X.real(), (_T)_X.imag()) {}
  262. complex<double>::complex(const complex<long double>& _X)
  263.     : _Complex_base<double>((_T)_X.real(), (_T)_X.imag()) {}
  264. complex<long double>::complex(const complex<float>& _X)
  265.     : _Complex_base<long double>((_T)_X.real(), (_T)_X.imag()) {}
  266. complex<long double>::complex(const complex<double>& _X)
  267.     : _Complex_base<long double>((_T)_X.real(), (_T)_X.imag()) {}
  268.         // TEMPLATE CLASS complex
  269. template<class _T>
  270.     class complex : public _Complex_base<_T> {
  271. public:
  272.     complex(const _T& _R = 0, const _T& _I = 0)
  273.         : _Complex_base<_T>(_R, _I) {}
  274. #if _HAS_MEMBER_TEMPLATES
  275.     template<class _U>
  276. #else
  277.     typedef _T _U;
  278. #endif
  279.         complex(const complex<_U>& _X)
  280.         : _Complex_base<_T>((_T)_X.real(), (_T)_X.imag()) {}
  281.     };
  282. #if !_HAS_MEMBER_TEMPLATES
  283.         // TEMPLATE complex OPERATORS
  284. template<class _T, class _U> inline
  285.     complex<_T>& operator=(complex<_T>& _X, const complex<_U>& _Y)
  286.     {_X.real((_T)_X.real());
  287.     _X.imag((_T)_X.imag());
  288.     return (_X); }
  289. template<class _T, class _U> complex<_T>& operator+=(
  290.     complex<_T>& _X,
  291.     const complex<_U>& _Y)
  292.     {_X.real(_X.real() + (_T)_Y.real());
  293.     _X.imag(_X.imag() + (_T)_Y.imag());
  294.     return (_X); }
  295. template<class _T, class _U> complex<_T>& operator-=(
  296.     complex<_T>& _X,
  297.     const complex<_U>& _Y)
  298.     {_X.real(_X.real() - (_T)_Y.real());
  299.     _X.imag(_X.imag() - (_T)_Y.imag());
  300.     return (_X); }
  301. template<class _T, class _U> complex<_T>& operator*=(
  302.     complex<_T>& _X,
  303.     const complex<_U>& _Y)
  304.     {_T _Yre = (_T)_Y.real();
  305.     _T _Yim = (_T)_Y.imag();
  306.     _T _W = _X.real() * _Yre - _X.imag() * _Yim;
  307.     _X.imag(_X.real() * _Yim + _X.imag() * _Yre);
  308.     _X.real(_W);
  309.     return (_X); }
  310. template<class _T, class _U> complex<_T>& operator/=(
  311.     complex<_T>& _X,
  312.     const complex<_U>& _Y)
  313.     {_T _Yre = (_T)_Y.real();
  314.     _T _Yim = (_T)_Y.imag();
  315.     if (_Ctr<_T>::_Isnan(_Yre) || _Ctr<_T>::_Isnan(_Yim))
  316.         _X.real(_Ctr<_T>::_Nanv(_Yre)), _X.imag(_X.real());
  317.     else if ((_Yim < 0 ? -_Yim : +_Yim)
  318.         < (_Yre < 0 ? -_Yre : +_Yre))
  319.         {_T _Wr = _Yim / _Yre;
  320.         _T _Wd = _Yre + _Wr * _Yim;
  321.         if (_Ctr<_T>::_Isnan(_Wd) || _Wd == 0)
  322.             _X.real(_Ctr<_T>::_Nanv(_Yre)), _X.imag(_X.real());
  323.         else
  324.             {_T _W = (_X.real() + _X.imag() * _Wr) / _Wd;
  325.             _X.imag((_X.imag() - _X.real() * _Wr) / _Wd);
  326.             _X.real(_W); }}
  327.     else if (_Yim == 0)
  328.         _X.real(_Ctr<_T>::_Nanv(_Yre)), _X.imag(_X.real());
  329.     else
  330.         {_T _Wr = _Yre / _Yim;
  331.         _T _Wd = _Yim + _Wr * _Yre;
  332.         if (_Ctr<_T>::_Isnan(_Wd) || _Wd == 0)
  333.             _X.real(_Ctr<_T>::_Nanv(_Yre)), _X.imag(_X.real());
  334.         else
  335.             {_T _W = (_X.real() * _Wr + _X.imag()) / _Wd;
  336.             _X.imag((_X.imag() * _Wr - _X.real()) / _Wd);
  337.             _X.real(_W); }}
  338.     return (_X); }
  339. #endif
  340.         // TEMPLATE FUNCTION imag
  341. template<class _T> inline
  342.     _T imag(const complex<_T>& _X)
  343.     {return (_X.imag()); }
  344.         // TEMPLATE FUNCTION real
  345. template<class _T> inline
  346.     _T real(const complex<_T>& _X)
  347.     {return (_X.real()); }
  348.         // TEMPLATE FUNCTION _Fabs
  349. template<class _T> inline
  350.     _T _Fabs(const complex<_T>& _X, int *_Pexp)
  351.     {*_Pexp = 0;
  352.     _T _A = real(_X);
  353.     _T _B = imag(_X);
  354.     if (_Ctr<_T>::_Isnan(_A))
  355.         return (_A);
  356.     else if (_Ctr<_T>::_Isnan(_B))
  357.         return (_B);
  358.     else
  359.         {if (_A < 0)
  360.             _A = -_A;
  361.         if (_B < 0)
  362.             _B = -_B;
  363.         if (_A < _B)
  364.             {_T _W = _A;
  365.             _A = _B, _B = _W; }
  366.         if (_A == 0 || _Ctr<_T>::_Isinf(_A))
  367.             return (_A);
  368.         if (1 <= _A)
  369.             *_Pexp = 2, _A *= 0.25, _B *= 0.25;
  370.         else
  371.             *_Pexp = -2, _A *= 4, _B *= 4;
  372.         _T _W = _A - _B;
  373.         if (_W == _A)
  374.             return (_A);
  375.         else if (_B < _W)
  376.             {const _T _Q = _A / _B;
  377.             return (_A + _B
  378.                 / (_Q + _Ctr<_T>::sqrt(_Q * _Q + 1))); }
  379.         else
  380.             {static const _T _R2 = 1.4142135623730950488L;
  381.             static const _T _Xh = 2.4142L;
  382.             static const _T _Xl = 0.0000135623730950488016887L;
  383.             const _T _Q = _W / _B;
  384.             const _T _R = (_Q + 2) * _Q;
  385.             const _T _S = _R / (_R2 + _Ctr<_T>::sqrt(_R + 2))
  386.                 + _Xl + _Q + _Xh;
  387.             return (_A + _B / _S); }}}
  388.         // TEMPLATE FUNCTION operator+
  389. template<class _T> inline
  390.     complex<_T> operator+(const complex<_T>& _L,
  391.         const complex<_T>& _R)
  392.     {return (complex<_T>(_L) += _R); }
  393. template<class _T> inline
  394.     complex<_T> operator+(const complex<_T>& _L, const _T& _R)
  395.     {complex<_T> _W(_L);
  396.     _W.real(_W.real() + _R);
  397.     return (_W); }
  398. template<class _T> inline
  399.     complex<_T> operator+(const _T& _L, const complex<_T>& _R)
  400.     {return (complex<_T>(_L) += _R); }
  401.         // TEMPLATE FUNCTION operator-
  402. template<class _T> inline
  403.     complex<_T> operator-(const complex<_T>& _L,
  404.         const complex<_T>& _R)
  405.     {return (complex<_T>(_L) -= _R); }
  406. template<class _T> inline
  407.     complex<_T> operator-(const complex<_T>& _L, const _T& _R)
  408.     {complex<_T> _W(_L);
  409.     _W.real(_W.real() - _R);
  410.     return (_W); }
  411. template<class _T> inline
  412.     complex<_T> operator-(const _T& _L, const complex<_T>& _R)
  413.     {return (complex<_T>(_L) -= _R); }
  414.         // TEMPLATE FUNCTION operator*
  415. template<class _T> inline
  416.     complex<_T> operator*(const complex<_T>& _L,
  417.         const complex<_T>& _R)
  418.     {return (complex<_T>(_L) *= _R); }
  419. template<class _T> inline
  420.     complex<_T> operator*(const complex<_T>& _L, const _T& _R)
  421.     {complex<_T> _W(_L);
  422.     _W.real(_W.real() * _R);
  423.     _W.imag(_W.imag() * _R);
  424.     return (_W); }
  425. template<class _T> inline
  426.     complex<_T> operator*(const _T& _L, const complex<_T>& _R)
  427.     {return (complex<_T>(_L) *= _R); }
  428.         // TEMPLATE FUNCTION operator/
  429. template<class _T> inline
  430.     complex<_T> operator/(const complex<_T>& _L,
  431.         const complex<_T>& _R)
  432.     {return (complex<_T>(_L) /= _R); }
  433. template<class _T> inline
  434.     complex<_T> operator/(const complex<_T>& _L, const _T& _R)
  435.     {complex<_T> _W(_L);
  436.     _W.real(_W.real() / _R);
  437.     _W.imag(_W.imag() / _R);
  438.     return (_W); }
  439. template<class _T> inline
  440.     complex<_T> operator/(const _T& _L, const complex<_T>& _R)
  441.     {return (complex<_T>(_L) /= _R); }
  442.         // TEMPLATE FUNCTION UNARY operator+
  443. template<class _T> inline
  444.     complex<_T> operator+(const complex<_T>& _L)
  445.     {return (complex<_T>(_L)); }
  446.         // TEMPLATE FUNCTION UNARY operator-
  447. template<class _T> inline
  448.     complex<_T> operator-(const complex<_T>& _L)
  449.     {return (complex<_T>(-real(_L), -imag(_L))); }
  450.         // TEMPLATE FUNCTION operator==
  451. template<class _T> inline
  452.     bool operator==(const complex<_T>& _L, const complex<_T>& _R)
  453.     {return (real(_L) == real(_R) && imag(_L) == imag(_R)); }
  454. template<class _T> inline
  455.     bool operator==(const complex<_T>& _L, const _T& _R)
  456.     {return (real(_L) == _R && imag(_L) == 0); }
  457. template<class _T> inline
  458.     bool operator==(const _T& _L, const complex<_T>& _R)
  459.     {return (_L == real(_R) && 0 == imag(_R)); }
  460.         // TEMPLATE FUNCTION operator!=
  461. //template<class _T> inline
  462. //    bool operator!=(const complex<_T>& _L, const complex<_T>& _R)
  463. //    {return (!(_L == _R)); }
  464. template<class _T> inline
  465.     bool operator!=(const complex<_T>& _L, const _T& _R)
  466.     {return (!(_L == _R)); }
  467. template<class _T> inline
  468.     bool operator!=(const _T& _L, const complex<_T>& _R)
  469.     {return (!(_L == _R)); }
  470.         // TEMPLATE FUNCTION operator>>
  471. template<class _T> inline
  472.     istream& operator>>(istream& _I, complex<_T>& _X)
  473.     {char _Ch;
  474.     long double _Re, _Im;
  475.     if (_I >> _Ch && _Ch != '(')
  476.         _I.putback(_Ch), _I >> _Re, _Im = 0;
  477.     else if (_I >> _Re >> _Ch && _Ch != ',')
  478.         if (_Ch == ')')
  479.             _Im = 0;
  480.         else
  481.             _I.putback(_Ch), _I.setstate(ios_base::failbit);
  482.     else if (_I >> _Im >> _Ch && _Ch != ')')
  483.             _I.putback(_Ch), _I.setstate(ios_base::failbit);
  484.     if (!_I.fail())
  485.         _X = complex<_T>((_T)_Re, (_T)_Im);
  486.     return (_I); }
  487.         // TEMPLATE FUNCTION operator<<
  488. template<class _T> inline
  489.     ostream& operator<<(ostream& _O, const complex<_T>& _X)
  490.     {return (_O << '(' << real(_X) << ',' << imag(_X) << ')'); }
  491.         // TEMPLATE FUNCTION abs
  492. template<class _T> inline
  493.     _T abs(const complex<_T>& _X)
  494.     {int _Xexp;
  495.     _T _Rho = _Fabs(_X, &_Xexp);
  496.     return (_Xexp == 0 ? _Rho : _Ctr<_T>::ldexp(_Rho, _Xexp)); }
  497.         // TEMPLATE FUNCTION arg
  498. template<class _T> inline
  499.     _T arg(const complex<_T>& _X)
  500.     {return (_Ctr<_T>::atan2(imag(_X), real(_X))); }
  501.         // TEMPLATE FUNCTION conjg
  502. template<class _T> inline
  503.     complex<_T> conj(const complex<_T>& _X)
  504.     {return (complex<_T>(real(_X), -imag(_X))); }
  505.         // TEMPLATE FUNCTION cos
  506. template<class _T> inline
  507.     complex<_T> cos(const complex<_T>& _X)
  508.     {return (complex<_T>(
  509.         _Ctr<_T>::_Cosh(imag(_X), _Ctr<_T>::cos(real(_X))),
  510.         -_Ctr<_T>::_Sinh(imag(_X), _Ctr<_T>::sin(real(_X))))); }
  511.         // TEMPLATE FUNCTION cosh
  512. template<class _T> inline
  513.     complex<_T> cosh(const complex<_T>& _X)
  514.     {return (complex<_T>(
  515.         _Ctr<_T>::_Cosh(real(_X), _Ctr<_T>::cos(imag(_X))),
  516.         _Ctr<_T>::_Sinh(real(_X), _Ctr<_T>::sin(imag(_X))))); }
  517.         // TEMPLATE FUNCTION exp
  518. template<class _T> inline
  519.     complex<_T> exp(const complex<_T>& _X)
  520.     {_T _Re(real(_X)), _Im(real(_X));
  521.     _Ctr<_T>::_Exp(&_Re, _Ctr<_T>::cos(imag(_X)), 0);
  522.     _Ctr<_T>::_Exp(&_Im, _Ctr<_T>::sin(imag(_X)), 0);
  523.     return (complex<_T>(_Re, _Im)); }
  524.         // TEMPLATE FUNCTION log
  525. template<class _T> inline
  526.     complex<_T> log(const complex<_T>& _X)
  527.     {int _Xexp;
  528.     _T _Rho = _Fabs(_X, &_Xexp);
  529.     if (_Ctr<_T>::_Isnan(_Rho))
  530.         return (complex<_T>(_Rho, _Rho));
  531.     else
  532.         {static const _T _Cm = 22713.0 / 32768.0;
  533.         static const _T _Cl = 1.428606820309417232e-6L;
  534.         _T _Xn = _Xexp;
  535.         complex<_T> _W(_Rho == 0 ? -_Ctr<_T>::_Infv(_Rho)
  536.             : _Ctr<_T>::_Isinf(_Rho) ? _Rho
  537.             : _Ctr<_T>::log(_Rho) + _Xn * _Cl + _Xn * _Cm,
  538.                 _Ctr<_T>::atan2(imag(_X), real(_X)));
  539.         return (_W); }}
  540.         // TEMPLATE FUNCTION log10
  541. template<class _T> inline
  542.     complex<_T> log10(const complex<_T>& _X)
  543.     {return (log(_X) * (_T)0.4342944819032518276511289L); }
  544.         // TEMPLATE FUNCTION norm
  545. template<class _T> inline
  546.     _T norm(const complex<_T>& _X)
  547.     {return (real(_X) * real(_X) + imag(_X) * imag(_X)); }
  548.         // TEMPLATE FUNCTION polar
  549. template<class _T> inline
  550.     complex<_T> polar(const _T& _Rho, const _T& _Theta)
  551.     {return (complex<_T>(_Rho * _Ctr<_T>::cos(_Theta),
  552.         _Rho * _Ctr<_T>::sin(_Theta))); }
  553.         // TEMPLATE FUNCTION pow
  554. template<class _T> inline
  555.     complex<_T> pow(const complex<_T>& _X, const complex<_T>& _Y)
  556.     {return (imag(_Y) == 0 ? pow(_X, real(_Y))
  557.         : imag(_X) == 0 ? complex<_T>(pow(real(_X), _Y))
  558.         : exp(_Y * log(_X))); }
  559. template<class _T> inline
  560.     complex<_T> pow(const complex<_T>& _X, const _T& _Y)
  561.     {return (imag(_X) == 0 ? complex<_T>(
  562.         _Ctr<_T>::pow(real(_X), _Y))
  563.         : exp(_Y * log(_X))); }
  564. template<class _T> inline
  565.     complex<_T> pow(const complex<_T>& _X, int _Y)
  566.     {if (imag(_X) == 0)
  567.         return (complex<_T>(pow(real(_X), _Y)));
  568.     else
  569.         return (_Pow_int(complex<_T>(_X), _Y)); }
  570. template<class _T> inline
  571.     complex<_T> pow(const _T& _X, const complex<_T>& _Y)
  572.     {return (imag(_Y) == 0
  573.         ? complex<_T>(_Ctr<_T>::pow(_X, real(_Y)))
  574.         : exp(_Y * _Ctr<_T>::log(_X))); }
  575.         // TEMPLATE FUNCTION sin
  576. template<class _T> inline
  577.     complex<_T> sin(const complex<_T>& _X)
  578.     {return (complex<_T>(
  579.         _Ctr<_T>::_Cosh(imag(_X), _Ctr<_T>::sin(real(_X))),
  580.         _Ctr<_T>::_Sinh(imag(_X), _Ctr<_T>::cos(real(_X))))); }
  581.         // TEMPLATE FUNCTION sinh
  582. template<class _T> inline
  583.     complex<_T> sinh(const complex<_T>& _X)
  584.     {return (complex<_T>(
  585.         _Ctr<_T>::_Sinh(real(_X), _Ctr<_T>::cos(imag(_X))),
  586.         _Ctr<_T>::_Cosh(real(_X), _Ctr<_T>::sin(imag(_X))))); }
  587.         // TEMPLATE FUNCTION sqrt
  588. template<class _T> inline
  589.     complex<_T> sqrt(const complex<_T>& _X)
  590.     {int _Xexp;
  591.     _T _Rho = _Fabs(_X, &_Xexp);
  592.     if (_Xexp == 0)
  593.         return (complex<_T>(_Rho, _Rho));
  594.     else
  595.         {_T _Remag = _Ctr<_T>::ldexp(real(_X) < 0
  596.             ? - real(_X) : real(_X), -_Xexp);
  597.         _Rho = _Ctr<_T>::ldexp(_Ctr<_T>::sqrt(
  598.             2 * (_Remag + _Rho)), _Xexp / 2 - 1);
  599.         if (0 <= real(_X))
  600.             return (complex<_T>(_Rho, imag(_X) / (2 * _Rho)));
  601.         else if (imag(_X) < 0)
  602.             return (complex<_T>(-imag(_X) / (2 * _Rho), -_Rho));
  603.         else
  604.             return (complex<_T>(imag(_X) / (2 * _Rho), _Rho)); }}
  605. _STD_END
  606. #endif /* _COMPLEX_ */
  607.  
  608.  
  609.  
  610.